library(deconstructSigs)
library(BSgenome)
library(BSgenome.Celegans.UCSC.ce11)
library(BSgenome.Hsapiens.UCSC.hg19)
human_genome <- 'BSgenome.Hsapiens.UCSC.hg19'
source('~/Mutation accumulation/dnarepairdefiiencies/plotting_functions.R')
source('~/Desktop/Git/phd/useful_functions.R')

These are the latest COSMIC signatures:

sbs_cancer_signatures <- read.csv('~/Downloads/sigProfiler_SBS_signatures_2019_05_22.csv')[,3:67]
dbs_cancer_signatures <- read.csv('~/Downloads/sigProfiler_DBS_signatures.csv', row.names = 1)
id_cancer_signatures <- read.csv('~/Downloads/sigProfiler_ID_signatures.csv', row.names = 1)

Some SBS signatures:

Some DNV signatures:

plot_id_only(dbs_cancer_signatures[,c('DBS1','DBS2')])

Adjusting the worm trinucleotide context to human genome:

worm.trinucl.counts
    AAA     AAC     AAG     AAT     ACA     ACC     ACG     ACT     AGA     AGC     AGG     AGT     ATA     ATC     ATG     ATT     CAA     CAC     CAG 
6285644 1815116 1728559 3741813 1721313  856618  792574 1475960 1800396  967792  833982 1473191 2015069 1531789 1582131 3745527 2414319 1067544 1142800 
    CAT     CCA     CCC     CCG     CCT     CGA     CGC     CGG     CGT     CTA     CTC     CTG     CTT     GAA     GAC     GAG     GAT     GCA     GCC 
1579669 1235912  596780  694118  838826 1093194  555188  689493  793540 1055154 1155528 1142397 1726417 2684274  860331 1151169 1535469 1123127  696495 
    GCG     GCT     GGA     GGC     GGG     GGT     GTA     GTC     GTG     GTT     TAA     TAC     TAG     TAT     TCA     TCC     TCG     TCT     TGA 
 553468  967223 1211898  692334  586758  853675 1101184  860019 1064808 1814847 2186895 1103474 1052833 2017565 2123980 1215740 1091255 1797486 2125754 
    TGC     TGG     TGT     TTA     TTC     TTG     TTT 
1124999 1234435 1720453 2189361 2681125 2416305 6285503 

Upload worm signatures

load('yoda1/beta_G_M_prior_I_greta_270919_5b_trunc.RData')

Plot some

Now adjust the base sub and dinucleotide subs of the most interesting signatures to the human genome.

Now compare them

cbind(colnames(humanized.sbs)[similar[,1]],colnames(sbs_cancer_signatures)[similar[,2]])
      [,1]               [,2]   
 [1,] "Mechlorethamine"  "SBS3" 
 [2,] "Radiation"        "SBS3" 
 [3,] "Mitomycin"        "SBS3" 
 [4,] "Radiation"        "SBS5" 
 [5,] "EMS"              "SBS7b"
 [6,] "polk.1.mms"       "SBS7c"
 [7,] "EMS"              "SBS11"
 [8,] "Cisplatin"        "SBS20"
 [9,] "xpf.1.cis"        "SBS20"
[10,] "xpc.1.cis"        "SBS20"
[11,] "AristolochicAcid" "SBS22"
[12,] "xpc.1.aa"         "SBS22"
[13,] "EMS"              "SBS23"
[14,] "Aflatoxin.B1"     "SBS24"
[15,] "xpf.1.aa"         "SBS27"
[16,] "Aflatoxin.B1"     "SBS29"
[17,] "EMS"              "SBS30"
[18,] "xpc.1"            "SBS40"
[19,] "xpf.1"            "SBS40"
[20,] "Radiation"        "SBS40"
[21,] "Xray"             "SBS40"
[22,] "Mitomycin"        "SBS40"
[23,] "mlh.1"            "SBS44"

Now plot them side by side

Now let’s compare DNV signatures.

names(diinucleotide.freq.factor) <- unique(dnv.types)
Error in names(diinucleotide.freq.factor) <- unique(dnv.types) : 
  object 'diinucleotide.freq.factor' not found

Need to upload the high-res DNV spectra and extract signatures.

dnv.sigs <- nmSolve(D = dnvY, P = X)
4

Now visualize some

Now adjust for human frequencies and compare

Compare

cbind(colnames(humanized.dbs)[similar[,1]],colnames(dbs_cancer_signatures)[similar[,2]])
      [,1]                       [,2]   
 [1,] "xpf.1.UV"                 "DBS1" 
 [2,] "xpa.1.Radiation"          "DBS2" 
 [3,] "xpc.1.Radiation"          "DBS2" 
 [4,] "bub.3..gt2000..Radiation" "DBS2" 
 [5,] "bub.3..ok3437..Radiation" "DBS2" 
 [6,] "rif.1.Radiation"          "DBS2" 
 [7,] "brc.1.MMS"                "DBS7" 
 [8,] "xpc.1.MMS"                "DBS7" 
 [9,] "csb.1.MMS"                "DBS7" 
[10,] "xpa.1.MMS"                "DBS7" 
[11,] "agt.1.MMS"                "DBS7" 
[12,] "polk.1.MMS"               "DBS7" 
[13,] "ced.3.MMS"                "DBS7" 
[14,] "mus.81.MMS"               "DBS7" 
[15,] "xpf.1.UV"                 "DBS11"

DBS11 has no known aetiology, maybe APOBEC mutations. Is not really similar to xpf-1:UV.

Now let’s look at the indel profiles (these are quite tricky to adjust so I’ll compare them on the worm scale).

colnames(Y)[99:112]
 [1] "D.1.rep"      "D.1.nonrep"   "D.2.5.rep"    "D.2.5.nonrep" "D.5.50"       "D.50.400"     "DI.small"     "DI.large"     "I.1.rep"      "I.1.nonrep"  
[11] "I.2.5.rep"    "I.2.5.nonrep" "I.5.50"       "I.50.400"    
regrouped.id.sigs <- rbind(colSums(id_cancer_signatures[c(3:6,9:12),]), colSums(id_cancer_signatures[c(1:2,7:8),]),
                           colSums(id_cancer_signatures[c(27:30,33:36,39:42),]), colSums(id_cancer_signatures[c(25:26,31:32,37:38,73:78),]),
                           colSums(id_cancer_signatures[c(43:48,79:83),]), 0,
                           0,0,
                           colSums(id_cancer_signatures[c(15:18,21:24),]), colSums(id_cancer_signatures[c(13:14,19:20),]),
                           colSums(id_cancer_signatures[c(51:54,57:60,63:66),]), colSums(id_cancer_signatures[c(49:50,55:56,61:62),]),
                           colSums(id_cancer_signatures[c(67:72),]), 0)
rownames(regrouped.id.sigs)  <- colnames(Y)[99:112]

LS0tCnRpdGxlOiAiQ29tcGFyaW5nIHRoZSBzaWduYXR1cmVzIGJldHdlZW4gd29ybXMgYW5kIGNhbmNlcnMiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCmBgYHtyfQpsaWJyYXJ5KGRlY29uc3RydWN0U2lncykKbGlicmFyeShCU2dlbm9tZSkKbGlicmFyeShCU2dlbm9tZS5DZWxlZ2Fucy5VQ1NDLmNlMTEpCmxpYnJhcnkoQlNnZW5vbWUuSHNhcGllbnMuVUNTQy5oZzE5KQpodW1hbl9nZW5vbWUgPC0gJ0JTZ2Vub21lLkhzYXBpZW5zLlVDU0MuaGcxOScKc291cmNlKCd+L011dGF0aW9uIGFjY3VtdWxhdGlvbi9kbmFyZXBhaXJkZWZpaWVuY2llcy9wbG90dGluZ19mdW5jdGlvbnMuUicpCnNvdXJjZSgnfi9EZXNrdG9wL0dpdC9waGQvdXNlZnVsX2Z1bmN0aW9ucy5SJykKYGBgCgoKVGhlc2UgYXJlIHRoZSBsYXRlc3QgQ09TTUlDIHNpZ25hdHVyZXM6CgpgYGB7cn0Kc2JzX2NhbmNlcl9zaWduYXR1cmVzIDwtIHJlYWQuY3N2KCd+L0Rvd25sb2Fkcy9zaWdQcm9maWxlcl9TQlNfc2lnbmF0dXJlc18yMDE5XzA1XzIyLmNzdicpWywzOjY3XQpkYnNfY2FuY2VyX3NpZ25hdHVyZXMgPC0gcmVhZC5jc3YoJ34vRG93bmxvYWRzL3NpZ1Byb2ZpbGVyX0RCU19zaWduYXR1cmVzLmNzdicsIHJvdy5uYW1lcyA9IDEpCmlkX2NhbmNlcl9zaWduYXR1cmVzIDwtIHJlYWQuY3N2KCd+L0Rvd25sb2Fkcy9zaWdQcm9maWxlcl9JRF9zaWduYXR1cmVzLmNzdicsIHJvdy5uYW1lcyA9IDEpCmBgYAoKU29tZSBTQlMgc2lnbmF0dXJlczoKCmBgYHtyfQpwbG90X3NpZ193YihzYnNfY2FuY2VyX3NpZ25hdHVyZXNbLGMoJ1NCUzQnLCdTQlMyOScpXSkKYGBgCgpTb21lIEROViBzaWduYXR1cmVzOgoKYGBge3J9CnBsb3RfaWRfb25seShkYnNfY2FuY2VyX3NpZ25hdHVyZXNbLGMoJ0RCUzEnLCdEQlMyJyldKQpgYGAKCkFkanVzdGluZyB0aGUgd29ybSB0cmludWNsZW90aWRlIGNvbnRleHQgdG8gaHVtYW4gZ2Vub21lOgoKYGBge3J9CmxpYnJhcnkoZGVjb25zdHJ1Y3RTaWdzKQpnZW5vbWUgPC0gJ0JTZ2Vub21lLkNlbGVnYW5zLlVDU0MuY2UxMScKZ2Vub21lLnNlcSA8LSBnZXRTZXEoZ2V0KGdlbm9tZSkpWy03XQp3b3JtLnRyaW51Y2xlb3RpZGVzIDwtIGNvbFN1bXModHJpbnVjbGVvdGlkZUZyZXF1ZW5jeShnZW5vbWUuc2VxKSkKaHVtYW4udHJpbnVjbGVvdGlkZXMgPC0gYXMudmVjdG9yKHQodHJpLmNvdW50cy5nZW5vbWUpKSAjIC8gc3VtKHRyaS5jb3VudHMuZ2Vub21lKSkpICMgY291bnRzIGZyb20gImRlY29uc3RydWN0U2lncyIgcGFja2FnZQpuYW1lcyhodW1hbi50cmludWNsZW90aWRlcykgPC0gcm93Lm5hbWVzKHRyaS5jb3VudHMuZ2Vub21lKQp0cmludWNsZW90aWRlLmZyZXEuZmFjdG9yIDwtIHNhcHBseSh1bmlxdWUodHlwZXMpLCBmdW5jdGlvbih4KSB7CiAgZnJlcS53b3JtIDwtIHdvcm0udHJpbnVjbGVvdGlkZXNbeF0gKyB3b3JtLnRyaW51Y2xlb3RpZGVzW2FzLmNoYXJhY3RlcihyZXZlcnNlQ29tcGxlbWVudChETkFTdHJpbmcoeCkpKV0KICByZXR1cm4oZnJlcS53b3JtIC8gIGh1bWFuLnRyaW51Y2xlb3RpZGVzW3hdKSAjIHRyaS5jb3VudHMuZ2Vub21lIGlzIGFscmVhZHkgY2xhc3NpZmllZCB3LnIudC4gcHlyaW1pZGluZSByZWZlcmVuY2UKfSkKbmFtZXModHJpbnVjbGVvdGlkZS5mcmVxLmZhY3RvcikgPC0gdW5pcXVlKHR5cGVzKQpgYGAKClVwbG9hZCB3b3JtIHNpZ25hdHVyZXMKCmBgYHtyfQpsb2FkKCd5b2RhMS9iZXRhX0dfTV9wcmlvcl9JX2dyZXRhXzI3MDkxOV81Yl90cnVuYy5SRGF0YScpCmBgYAoKUGxvdCBzb21lCgpgYGB7cn0KY2xycyA8LSBjKCIjMkVCQUVEIiwiIzAwMDAwMCIsIiNERTFDMTQiLCIjRDREMkQyIiwiI0FEQ0M1NCIsIiNGMEQwQ0UiLAogICAgICAgICAgImJyb3duIiwiIzhERDNDNyIsIiNGRkZGQjMiLCIjQkVCQURBIiwiZGFya21hZ2VudGEiKQpwbG90X2Z1bGxzaWdfd2IoYmV0YV9NX2dyZXRhX2Z1bGxbLGMoJ01NUycsJ0VNUycpXSwgY29sb3JzID0gY2xycywgQ0kgPSBULCAKICAgICAgICAgICAgICAgIGxvdyA9IGJldGFfTV9ncmV0YV9mdWxsX2xvd1ssYygnTU1TJywnRU1TJyldLCBoaWdoID0gYmV0YV9NX2dyZXRhX2Z1bGxfaGlnaFssYygnTU1TJywnRU1TJyldKQpgYGAKCk5vdyBhZGp1c3QgdGhlIGJhc2Ugc3ViIGFuZCBkaW51Y2xlb3RpZGUgc3VicyBvZiB0aGUgbW9zdCBpbnRlcmVzdGluZyBzaWduYXR1cmVzIHRvIHRoZSBodW1hbiBnZW5vbWUuCgpgYGB7cn0KaHVtYW5pemVkLnNicyA8LSBkYXRhLmZyYW1lKGJldGFfR0hfZ3JldGFfZnVsbCwgYmV0YV9NX2dyZXRhX2Z1bGwsCiAgICAgICAgICAgICAgICAgICAgICAgcG9say4xLm1tcyA9IGJldGFfTV9ncmV0YV9mdWxsWywnTU1TJ10gKiBleHAoYmV0YV9JX2dyZXRhX2Z1bGxbLCdwb2xrLjEuTU1TJ10pLAogICAgICAgICAgICAgICAgICAgICAgIHBvbGsuMS5lbXMgPSBiZXRhX01fZ3JldGFfZnVsbFssJ0VNUyddICogZXhwKGJldGFfSV9ncmV0YV9mdWxsWywncG9say4xLkVNUyddKSwKICAgICAgICAgICAgICAgICAgICAgICByZXYuMy5tbXMgPSBiZXRhX01fZ3JldGFfZnVsbFssJ01NUyddICogZXhwKGJldGFfSV9ncmV0YV9mdWxsWywncmV2LjMuTU1TJ10pLAogICAgICAgICAgICAgICAgICAgICAgIHJldi4zLnV2ID0gYmV0YV9NX2dyZXRhX2Z1bGxbLCdVViddICogZXhwKGJldGFfSV9ncmV0YV9mdWxsWywncmV2LjMuTU1TJ10pLAogICAgICAgICAgICAgICAgICAgICAgIHhwZi4xLmFhID0gYmV0YV9NX2dyZXRhX2Z1bGxbLCdBcmlzdG9sb2NoaWNBY2lkJ10gKiBleHAoYmV0YV9JX2dyZXRhX2Z1bGxbLCd4cGYuMS5BcmlzdG9sb2NoaWNBY2lkJ10pLAogICAgICAgICAgICAgICAgICAgICAgIHhwYy4xLmFhID0gYmV0YV9NX2dyZXRhX2Z1bGxbLCdBcmlzdG9sb2NoaWNBY2lkJ10gKiBleHAoYmV0YV9JX2dyZXRhX2Z1bGxbLCd4cGMuMS5BcmlzdG9sb2NoaWNBY2lkJ10pLAogICAgICAgICAgICAgICAgICAgICAgIHhwYy4xLnV2ID0gYmV0YV9NX2dyZXRhX2Z1bGxbLCdVViddICogZXhwKGJldGFfSV9ncmV0YV9mdWxsWywneHBjLjEuVVYnXSksCiAgICAgICAgICAgICAgICAgICAgICAgeHBmLjEudXYgPSBiZXRhX01fZ3JldGFfZnVsbFssJ1VWJ10gKiBleHAoYmV0YV9JX2dyZXRhX2Z1bGxbLCd4cGYuMS5VViddKSwKICAgICAgICAgICAgICAgICAgICAgICB4cGEuMS5pciA9IGJldGFfTV9ncmV0YV9mdWxsWywnUmFkaWF0aW9uJ10gKiBleHAoYmV0YV9JX2dyZXRhX2Z1bGxbLCd4cGEuMS5SYWRpYXRpb24nXSksCiAgICAgICAgICAgICAgICAgICAgICAgeHBmLjEuY2lzID0gYmV0YV9NX2dyZXRhX2Z1bGxbLCdDaXNwbGF0aW4nXSAqIGV4cChiZXRhX0lfZ3JldGFfZnVsbFssJ3hwZi4xLkNpc3BsYXRpbiddKSwKICAgICAgICAgICAgICAgICAgICAgICB4cGMuMS5jaXMgPSBiZXRhX01fZ3JldGFfZnVsbFssJ0Npc3BsYXRpbiddICogZXhwKGJldGFfSV9ncmV0YV9mdWxsWywneHBjLjEuQ2lzcGxhdGluJ10pKVsxOjk2LF0KZm9yIChpIGluIDE6bmNvbChodW1hbml6ZWQuc2JzKSkgewogIGh1bWFuaXplZC5zYnNbLGldIDwtIGh1bWFuaXplZC5zYnNbLGldIC8gc3VtKGh1bWFuaXplZC5zYnNbLGldKQogIGh1bWFuaXplZC5zYnNbLGldIDwtIGh1bWFuaXplZC5zYnNbLGldIC8gd29ybS50cmludWNsZW90aWRlc1t0eXBlc10gKiBodW1hbi50cmludWNsZW90aWRlc1t0eXBlc10KICBodW1hbml6ZWQuc2JzWyxpXSA8LSBodW1hbml6ZWQuc2JzWyxpXSAvIHN1bShodW1hbml6ZWQuc2JzWyxpXSkKfQpwbG90X3NpZ193YihodW1hbml6ZWQuc2JzWyxjKCdOMicsJ01NUycpXSkKYGBgCgpOb3cgY29tcGFyZSB0aGVtCgpgYGB7cn0Kc2FwcGx5KDE6bmNvbChzYnNfY2FuY2VyX3NpZ25hdHVyZXMpLCBmdW5jdGlvbihpKSAKICBzYXBwbHkoMTpuY29sKGh1bWFuaXplZC5zYnMpLCBmdW5jdGlvbihqKSAKICAgIGNvc2luZShzYnNfY2FuY2VyX3NpZ25hdHVyZXNbLGldLCBodW1hbml6ZWQuc2JzWyxqXSkpKSAtPiBzaW1zCndoaWNoKHNpbXMgPiAwLjgsIGFyci5pbmQgPSBUKSAtPiBzaW1pbGFyCmNiaW5kKGNvbG5hbWVzKGh1bWFuaXplZC5zYnMpW3NpbWlsYXJbLDFdXSxjb2xuYW1lcyhzYnNfY2FuY2VyX3NpZ25hdHVyZXMpW3NpbWlsYXJbLDJdXSkKYGBgCgpOb3cgcGxvdCB0aGVtIHNpZGUgYnkgc2lkZQoKYGBge3J9Cmh1bWFuLnNpZy5pbmRpY2VzIDwtIHVuaXF1ZShzaW1pbGFyWywyXSkgIyAxNCBwbG90cyB0byBjaGVjawpwbG90X3NpZ193YihkYXRhLmZyYW1lKHNic19jYW5jZXJfc2lnbmF0dXJlc1ssaHVtYW4uc2lnLmluZGljZXNbMV0sZHJvcD1GXSwgaHVtYW5pemVkLnNic1ssc2ltaWxhcltzaW1pbGFyWywyXSA9PSBodW1hbi5zaWcuaW5kaWNlc1sxXSwxXV0pKQpgYGAKCmBgYHtyfQpwbG90X3NpZ193YihkYXRhLmZyYW1lKHNic19jYW5jZXJfc2lnbmF0dXJlc1ssaHVtYW4uc2lnLmluZGljZXNbMl0sZHJvcD1GXSwgaHVtYW5pemVkLnNic1ssc2ltaWxhcltzaW1pbGFyWywyXSA9PSBodW1hbi5zaWcuaW5kaWNlc1syXSwxLGRyb3A9Rl1dKSkKYGBgCgpgYGB7cn0KcGxvdF9zaWdfd2IoZGF0YS5mcmFtZShzYnNfY2FuY2VyX3NpZ25hdHVyZXNbLGh1bWFuLnNpZy5pbmRpY2VzWzNdLGRyb3A9Rl0sIGh1bWFuaXplZC5zYnNbLHNpbWlsYXJbc2ltaWxhclssMl0gPT0gaHVtYW4uc2lnLmluZGljZXNbM10sMV0sZHJvcD1GXSkpCmBgYAoKYGBge3J9CnBsb3Rfc2lnX3diKGRhdGEuZnJhbWUoc2JzX2NhbmNlcl9zaWduYXR1cmVzWyxodW1hbi5zaWcuaW5kaWNlc1s0XSxkcm9wPUZdLCBodW1hbml6ZWQuc2JzWyxzaW1pbGFyW3NpbWlsYXJbLDJdID09IGh1bWFuLnNpZy5pbmRpY2VzWzRdLDFdLGRyb3A9Rl0pKQpgYGAKCmBgYHtyfQpwbG90X3NpZ193YihkYXRhLmZyYW1lKHNic19jYW5jZXJfc2lnbmF0dXJlc1ssaHVtYW4uc2lnLmluZGljZXNbNV0sZHJvcD1GXSwgaHVtYW5pemVkLnNic1ssc2ltaWxhcltzaW1pbGFyWywyXSA9PSBodW1hbi5zaWcuaW5kaWNlc1s1XSwxXSxkcm9wPUZdKSkKYGBgCgpgYGB7cn0KcGxvdF9zaWdfd2IoZGF0YS5mcmFtZShzYnNfY2FuY2VyX3NpZ25hdHVyZXNbLGh1bWFuLnNpZy5pbmRpY2VzWzZdLGRyb3A9Rl0sIGh1bWFuaXplZC5zYnNbLHNpbWlsYXJbc2ltaWxhclssMl0gPT0gaHVtYW4uc2lnLmluZGljZXNbNl0sMV0sZHJvcD1GXSkpCmBgYAoKYGBge3J9CnBsb3Rfc2lnX3diKGRhdGEuZnJhbWUoc2JzX2NhbmNlcl9zaWduYXR1cmVzWyxodW1hbi5zaWcuaW5kaWNlc1s3XSxkcm9wPUZdLCBodW1hbml6ZWQuc2JzWyxzaW1pbGFyW3NpbWlsYXJbLDJdID09IGh1bWFuLnNpZy5pbmRpY2VzWzddLDFdLGRyb3A9Rl0pKQpgYGAKCmBgYHtyfQpwbG90X3NpZ193YihkYXRhLmZyYW1lKHNic19jYW5jZXJfc2lnbmF0dXJlc1ssaHVtYW4uc2lnLmluZGljZXNbOF0sZHJvcD1GXSwgaHVtYW5pemVkLnNic1ssc2ltaWxhcltzaW1pbGFyWywyXSA9PSBodW1hbi5zaWcuaW5kaWNlc1s4XSwxXSxkcm9wPUZdKSkKYGBgCgpgYGB7cn0KcGxvdF9zaWdfd2IoZGF0YS5mcmFtZShzYnNfY2FuY2VyX3NpZ25hdHVyZXNbLGh1bWFuLnNpZy5pbmRpY2VzWzldLGRyb3A9Rl0sIGh1bWFuaXplZC5zYnNbLHNpbWlsYXJbc2ltaWxhclssMl0gPT0gaHVtYW4uc2lnLmluZGljZXNbOV0sMV0sZHJvcD1GXSkpCmBgYAoKYGBge3J9CnBsb3Rfc2lnX3diKGRhdGEuZnJhbWUoc2JzX2NhbmNlcl9zaWduYXR1cmVzWyxodW1hbi5zaWcuaW5kaWNlc1sxMF0sZHJvcD1GXSwgaHVtYW5pemVkLnNic1ssc2ltaWxhcltzaW1pbGFyWywyXSA9PSBodW1hbi5zaWcuaW5kaWNlc1sxMF0sMV0sZHJvcD1GXSkpCmBgYAoKYGBge3J9CnBsb3Rfc2lnX3diKGRhdGEuZnJhbWUoc2JzX2NhbmNlcl9zaWduYXR1cmVzWyxodW1hbi5zaWcuaW5kaWNlc1sxMV0sZHJvcD1GXSwgaHVtYW5pemVkLnNic1ssc2ltaWxhcltzaW1pbGFyWywyXSA9PSBodW1hbi5zaWcuaW5kaWNlc1sxMV0sMV0sZHJvcD1GXSkpCmBgYAoKYGBge3J9CnBsb3Rfc2lnX3diKGRhdGEuZnJhbWUoc2JzX2NhbmNlcl9zaWduYXR1cmVzWyxodW1hbi5zaWcuaW5kaWNlc1sxMl0sZHJvcD1GXSwgaHVtYW5pemVkLnNic1ssc2ltaWxhcltzaW1pbGFyWywyXSA9PSBodW1hbi5zaWcuaW5kaWNlc1sxMl0sMV0sZHJvcD1GXSkpCmBgYAoKYGBge3J9CnBsb3Rfc2lnX3diKGRhdGEuZnJhbWUoc2JzX2NhbmNlcl9zaWduYXR1cmVzWyxodW1hbi5zaWcuaW5kaWNlc1sxM10sZHJvcD1GXSwgaHVtYW5pemVkLnNic1ssc2ltaWxhcltzaW1pbGFyWywyXSA9PSBodW1hbi5zaWcuaW5kaWNlc1sxM10sMV0sZHJvcD1GXSkpCmBgYAoKYGBge3J9CnBsb3Rfc2lnX3diKGRhdGEuZnJhbWUoc2JzX2NhbmNlcl9zaWduYXR1cmVzWyxodW1hbi5zaWcuaW5kaWNlc1sxNF0sZHJvcD1GXSwgaHVtYW5pemVkLnNic1ssc2ltaWxhcltzaW1pbGFyWywyXSA9PSBodW1hbi5zaWcuaW5kaWNlc1sxNF0sMV0sZHJvcD1GXSkpCmBgYAoKTm93IGxldCdzIGNvbXBhcmUgRE5WIHNpZ25hdHVyZXMuCgpgYGB7cn0KZG52LnR5cGVzIDwtIHN1YnN0cihkbnYudHlwZXMuZnVsbCwxLDIpCndvcm0uZGludWNsZW90aWRlcyA8LSBjb2xTdW1zKGRpbnVjbGVvdGlkZUZyZXF1ZW5jeShnZW5vbWUuc2VxKSkKaHVtYW4uZ2Vub21lLnNlcSA8LSBnZXRTZXEoZ2V0KGh1bWFuX2dlbm9tZSkpWzE6MjNdCmh1bWFuLmRpbnVjbGVvdGlkZXMgPC0gY29sU3VtcyhkaW51Y2xlb3RpZGVGcmVxdWVuY3koaHVtYW4uZ2Vub21lLnNlcSkpCmRpbnVjbGVvdGlkZS5mcmVxLmZhY3RvciA8LSBzYXBwbHkodW5pcXVlKGRudi50eXBlcyksIGZ1bmN0aW9uKHgpIHsKICBmcmVxLndvcm0gPC0gd29ybS5kaW51Y2xlb3RpZGVzW3hdICsgd29ybS5kaW51Y2xlb3RpZGVzW2FzLmNoYXJhY3RlcihyZXZlcnNlQ29tcGxlbWVudChETkFTdHJpbmcoeCkpKV0KICBmcmVxLmh1bWFuIDwtIGh1bWFuLmRpbnVjbGVvdGlkZXNbeF0gKyBodW1hbi5kaW51Y2xlb3RpZGVzW2FzLmNoYXJhY3RlcihyZXZlcnNlQ29tcGxlbWVudChETkFTdHJpbmcoeCkpKV0KICByZXR1cm4oZnJlcS53b3JtIC8gZnJlcS5odW1hbikgIyB0cmkuY291bnRzLmdlbm9tZSBpcyBhbHJlYWR5IGNsYXNzaWZpZWQgdy5yLnQuIHB5cmltaWRpbmUgcmVmZXJlbmNlCn0pCm5hbWVzKGRpbnVjbGVvdGlkZS5mcmVxLmZhY3RvcikgPC0gdW5pcXVlKGRudi50eXBlcykKYGBgCgpOZWVkIHRvIHVwbG9hZCB0aGUgaGlnaC1yZXMgRE5WIHNwZWN0cmEgYW5kIGV4dHJhY3Qgc2lnbmF0dXJlcy4KYGBge3J9CmRudi5zcGVjdHJ1bSA8LSByZWFkLmNzdignRE5WX3NwZWN0cnVtX21vc3RfcmVjZW50LmNzdicsIHJvdy5uYW1lcyA9IDEpWywxOjc4XQpsb2FkKCd5b2RhMS9NdXRhZ2VuX2dyZXRhX2RhdGEuUkRhdGEnKQpsb2FkKCd5b2RhMS9ETlZfc2lnbmF0dXJlc18wMjEwMjAxOS5SRGF0YScpCm11dGFnZW5faW5faW50ZXJhY3Rpb25zIDwtIHNhcHBseShjb2xuYW1lcyhiZXRhX0lfZ3JldGFfZnVsbCksIGZ1bmN0aW9uKHgpIGNvbG5hbWVzKE0xKVtNMVt3aGljaChXWyx4XT4wKVsxXSxdPjBdKQpkbnYuc2lncyA8LSBkYXRhLmZyYW1lKGJldGFfR0hfZ3JldGFfZnVsbCwgYmV0YV9NX2dyZXRhX2Z1bGwsIGJldGFfTV9ncmV0YV9mdWxsWyxtdXRhZ2VuX2luX2ludGVyYWN0aW9uc10gKiBleHAoYmV0YV9JX2dyZXRhX2Z1bGwpKQpjb2xuYW1lcyhkbnYuc2lncykgPC0gYyhjb2xuYW1lcyhiZXRhX0dIX2dyZXRhX2Z1bGwpLCBjb2xuYW1lcyhiZXRhX01fZ3JldGFfZnVsbCksIGNvbG5hbWVzKGJldGFfSV9ncmV0YV9mdWxsKSkKYGBgCgpOb3cgdmlzdWFsaXplIHNvbWUKYGBge3J9CnBsb3RfZG52X29ubHkoZG52LnNpZ3NbLGMoIlVWIiwiTWl0b215Y2luIildKQpgYGAKCk5vdyBhZGp1c3QgZm9yIGh1bWFuIGZyZXF1ZW5jaWVzIGFuZCBjb21wYXJlCgpgYGB7cn0KaHVtYW5pemVkLmRicyA8LSBkbnYuc2lncwpmb3IgKGkgaW4gMTpucm93KGRudi5zaWdzKSkgewogIGh1bWFuaXplZC5kYnNbaSxdIDwtIGRudi5zaWdzW2ksXSAvIHN1bShkbnYuc2lnc1tpLF0pCiAgaHVtYW5pemVkLmRic1tpLF0gPC0gaHVtYW5pemVkLmRic1tpLF0gLyBkaW51Y2xlb3RpZGUuZnJlcS5mYWN0b3JbZG52LnR5cGVzXQogIGh1bWFuaXplZC5kYnNbaSxdIDwtIGh1bWFuaXplZC5kYnNbaSxdIC8gc3VtKGh1bWFuaXplZC5kYnNbaSxdKQp9CnBsb3RfZG52X29ubHkoaHVtYW5pemVkLmRic1ssYygiVVYiLCJNTVMiKV0pCmBgYAoKQ29tcGFyZQoKYGBge3J9CnNhcHBseSgxOm5jb2woZGJzX2NhbmNlcl9zaWduYXR1cmVzKSwgZnVuY3Rpb24oaSkgCiAgc2FwcGx5KDE6bmNvbChodW1hbml6ZWQuZGJzKSwgZnVuY3Rpb24oaikgCiAgICBjb3NpbmUoZGJzX2NhbmNlcl9zaWduYXR1cmVzWyxpXSwgaHVtYW5pemVkLmRic1ssal0pKSkgLT4gc2ltcwp3aGljaChzaW1zID4gMC44LCBhcnIuaW5kID0gVCkgLT4gc2ltaWxhcgpjYmluZChjb2xuYW1lcyhodW1hbml6ZWQuZGJzKVtzaW1pbGFyWywxXV0sY29sbmFtZXMoZGJzX2NhbmNlcl9zaWduYXR1cmVzKVtzaW1pbGFyWywyXV0pCmBgYAoKCmBgYHtyfQpodW1hbi5zaWcuaW5kaWNlcyA8LSB1bmlxdWUoc2ltaWxhclssMl0pICMgNCBwbG90cyB0byBjaGVjawpwbG90X2Rudl9vbmx5KGRhdGEuZnJhbWUoZGJzX2NhbmNlcl9zaWduYXR1cmVzWyxodW1hbi5zaWcuaW5kaWNlc1sxXSxkcm9wPUZdLCBodW1hbml6ZWQuZGJzWyxzaW1pbGFyW3NpbWlsYXJbLDJdID09IGh1bWFuLnNpZy5pbmRpY2VzWzFdLDFdLGRyb3A9Rl0pKQpgYGAKCmBgYHtyfQpwbG90X2Rudl9vbmx5KGRhdGEuZnJhbWUoZGJzX2NhbmNlcl9zaWduYXR1cmVzWyxodW1hbi5zaWcuaW5kaWNlc1syXSxkcm9wPUZdLCBodW1hbml6ZWQuZGJzWyxzaW1pbGFyW3NpbWlsYXJbLDJdID09IGh1bWFuLnNpZy5pbmRpY2VzWzJdLDFdLGRyb3A9Rl0pKQpgYGAKCmBgYHtyfQpwbG90X2Rudl9vbmx5KGRhdGEuZnJhbWUoZGJzX2NhbmNlcl9zaWduYXR1cmVzWyxodW1hbi5zaWcuaW5kaWNlc1szXSxkcm9wPUZdLCBodW1hbml6ZWQuZGJzWyxzaW1pbGFyW3NpbWlsYXJbLDJdID09IGh1bWFuLnNpZy5pbmRpY2VzWzNdLDFdLGRyb3A9Rl0pKQpgYGAKCkRCUzExIGhhcyBubyBrbm93biBhZXRpb2xvZ3ksIG1heWJlIEFQT0JFQyBtdXRhdGlvbnMuIElzIG5vdCByZWFsbHkgc2ltaWxhciB0byB4cGYtMTpVVi4KCmBgYHtyfQpwbG90X2Rudl9vbmx5KGRhdGEuZnJhbWUoZGJzX2NhbmNlcl9zaWduYXR1cmVzWyxodW1hbi5zaWcuaW5kaWNlc1s0XSxkcm9wPUZdLCBodW1hbml6ZWQuZGJzWyxzaW1pbGFyW3NpbWlsYXJbLDJdID09IGh1bWFuLnNpZy5pbmRpY2VzWzRdLDFdLGRyb3A9Rl0pKQpgYGAKCk5vdyBsZXQncyBsb29rIGF0IHRoZSBpbmRlbCBwcm9maWxlcyAodGhlc2UgYXJlIHF1aXRlIHRyaWNreSB0byBhZGp1c3Qgc28gSSdsbCBjb21wYXJlIHRoZW0gb24gdGhlIHdvcm0gc2NhbGUpLgoKYGBge3J9CmNvbG5hbWVzKFkpWzk5OjExMl0KYGBgCgpgYGB7cn0KcmVncm91cGVkLmlkLnNpZ3MgPC0gcmJpbmQoY29sU3VtcyhpZF9jYW5jZXJfc2lnbmF0dXJlc1tjKDM6Niw5OjEyKSxdKSwgY29sU3VtcyhpZF9jYW5jZXJfc2lnbmF0dXJlc1tjKDE6Miw3OjgpLF0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xTdW1zKGlkX2NhbmNlcl9zaWduYXR1cmVzW2MoMjc6MzAsMzM6MzYsMzk6NDIpLF0pLCBjb2xTdW1zKGlkX2NhbmNlcl9zaWduYXR1cmVzW2MoMjU6MjYsMzE6MzIsMzc6MzgsNzM6NzgpLF0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xTdW1zKGlkX2NhbmNlcl9zaWduYXR1cmVzW2MoNDM6NDgsNzk6ODMpLF0pLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAwLDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbFN1bXMoaWRfY2FuY2VyX3NpZ25hdHVyZXNbYygxNToxOCwyMToyNCksXSksIGNvbFN1bXMoaWRfY2FuY2VyX3NpZ25hdHVyZXNbYygxMzoxNCwxOToyMCksXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbFN1bXMoaWRfY2FuY2VyX3NpZ25hdHVyZXNbYyg1MTo1NCw1Nzo2MCw2Mzo2NiksXSksIGNvbFN1bXMoaWRfY2FuY2VyX3NpZ25hdHVyZXNbYyg0OTo1MCw1NTo1Niw2MTo2MiksXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbFN1bXMoaWRfY2FuY2VyX3NpZ25hdHVyZXNbYyg2Nzo3MiksXSksIDApCnJvd25hbWVzKHJlZ3JvdXBlZC5pZC5zaWdzKSAgPC0gY29sbmFtZXMoWSlbOTk6MTEyXQpgYGAKCmBgYHtyfQpmb3IgKGkgaW4gMToxNykKICBiYXJwbG90KHJlZ3JvdXBlZC5pZC5zaWdzWyxpXSwgY29sID0gYyhyZXAoY2xyc1s4XSw2KSwgcmVwKGNscnNbOV0sMiksIHJlcChjbHJzWzEwXSw2KSksIGxhcyA9IDIpCmBgYAoKYGBge3J9CmxvYWQoJ3lvZGExL2JldGFfR19NX3ByaW9yX0lfZ3JldGFfMjcwOTE5XzViX3RydW5jLlJEYXRhJykKYWxsLnNpZ3MgPC0gZGF0YS5mcmFtZShiZXRhX0dIX2dyZXRhX2Z1bGwsIGJldGFfTV9ncmV0YV9mdWxsLCBiZXRhX01fZ3JldGFfZnVsbFssbXV0YWdlbl9pbl9pbnRlcmFjdGlvbnNdICogZXhwKGJldGFfSV9ncmV0YV9mdWxsKSkKY29sbmFtZXMoYWxsLnNpZ3MpIDwtIGMoY29sbmFtZXMoYmV0YV9HSF9ncmV0YV9mdWxsKSwgY29sbmFtZXMoYmV0YV9NX2dyZXRhX2Z1bGwpLCBjb2xuYW1lcyhiZXRhX0lfZ3JldGFfZnVsbCkpCm5hbWVzKHdoaWNoKGNvbFN1bXMoYWxsLnNpZ3NbOTk6MTEyLF0pPjMpKSAtPiBpbmRlbHMudG8ucGxvdApmb3IgKGkgaW4gMTpsZW5ndGgoaW5kZWxzLnRvLnBsb3QpKQogIGJhcnBsb3QoYWxsLnNpZ3NbOTk6MTEyLGluZGVscy50by5wbG90W2ldXSwgY29sID0gYyhyZXAoY2xyc1s4XSw2KSwgcmVwKGNscnNbOV0sMiksIHJlcChjbHJzWzEwXSw2KSksIGxhcyA9IDIsIG1haW4gPSBpbmRlbHMudG8ucGxvdFtpXSkKYGBgCgo=